// ConfigFactory 是关于config的方法聚合，为上层domain提供基础调用
package aggregate

import (
	"gluenet/internal/glue-srvp/domain/dependency"
	"gluenet/internal/glue-srvp/domain/entity"
	"gluenet/internal/glue-srvp/domain/po"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

func init() {
	//fmt.Printf("init config factory\n")
	prepare.RegisterFactory(func() {
		configMetaFactory := NewConfigCreateFactory()
		prepare.InjectDependency(func() *ConfigFactory {
			return configMetaFactory
		})
	})
}

type ConfigFactory struct {
	ConfigMetaRepo dependency.ConfigMetaRepo
}

func (factory *ConfigFactory) AddConfig(auth infra.AuthInfo, req vo.CreateConfigReq) (*entity.Config, error) {
	var obj entity.Config
	if req.Kind == infra.ConfigKindHelmChart {
		obj.ConfigFile.IsUploads = true
		obj.ConfigFile.FileName = req.FileName
		obj.ConfigFile.UserId = auth.UserId
		obj.ConfigFile.Reader = req.FileReader
	}

	obj.Name = req.Name
	obj.Describe = req.Describe
	obj.Property = req.Property
	obj.Kind = req.Kind
	obj.Version = "1"
	obj.DetailRepoValue.KubeYaml = req.KubeYaml
	obj.DetailRepoValue.Charts = req.Charts
	obj.DetailRepoValue.OptionJaeger = req.OptionJaeger
	obj.DetailRepoValue.OptionLinkerd = req.OptionLinkerd
	obj.DetailRepoValue.OptionJaeger = req.OptionFlame

	obj.Tags = make([]po.Tag, len(req.Tags))
	for k, id := range req.Tags {
		obj.Tags[k].Id = id
	}

	if err := factory.ConfigMetaRepo.AddConfig(&obj, auth); err != nil {
		return nil, err
	}
	// todo make tag

	return &obj, nil
}

func (factory *ConfigFactory) UptConfig(auth infra.AuthInfo, req vo.UpdateConfigReq) (*entity.Config, error) {
	var obj entity.Config

	if err := factory.ConfigMetaRepo.FindOne(&obj, map[string]interface{}{
		"id": req.Id,
	}); err != nil {
		return nil, err
	}

	obj.Name = req.Name
	obj.Describe = req.Describe
	obj.Property = req.Property

	if obj.Kind == infra.ConfigKindKubeYaml && req.KubeYaml != nil {
		obj.DetailRepoValue.KubeYaml = req.KubeYaml
	}

	if err := factory.ConfigMetaRepo.UptConfig(&obj, auth); err != nil {
		return nil, err
	}

	return nil, nil
}

func (factory *ConfigFactory) DelConfig(auth infra.AuthInfo, id int64) (*entity.Config, error) {
	var obj entity.Config
	obj.Id = id

	if err := factory.ConfigMetaRepo.DelConfig(&obj, auth); err != nil {
		return nil, err
	}
	return &obj, nil
}

func (factory *ConfigFactory) Findby(auth infra.AuthInfo, query map[string]interface{}) ([]entity.Config, error) {
	var objs []entity.Config
	if query == nil {
		query = map[string]interface{}{}
	}
	query2 := make(map[string]interface{}, len(query))
	for k, v := range query {
		query2["srvp_config."+k] = v
	}
	if err := factory.ConfigMetaRepo.FindConfig(&objs, auth, query2); err != nil {
		return nil, err
	}
	return objs, nil
}

func NewConfigCreateFactory() *ConfigFactory {
	factory := &ConfigFactory{}
	prepare.FetchDependency(&factory.ConfigMetaRepo)
	return factory
}
